home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / GameboyDev / GBDK / examples / gb-dtmf / gb-dtmf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-29  |  14.6 KB  |  713 lines

  1. /* ---------------------------------------- */
  2. /*             GB-DTMF Ver1.0               */
  3. /*                  by                      */
  4. /*              Osamu Ohashi                */
  5. /* ---------------------------------------- */
  6.  
  7. #include <gb.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10.  
  11. /* BG data */
  12. #include "frm_lcd.c"    /* Back ground pattern */
  13. #include "brk_btn.c"    /* button image when broken */
  14. #include "prs_btn.c"    /* button image when pressed */
  15.  
  16. #include "dtmf_lcd.c"    /* LCD characters */
  17.  
  18. /* Sprite data */
  19. #include "key_num.c"    /* Sprite pattern for each key pad */
  20. #include "cursor.c"        /* cursor pattern */
  21.  
  22. /* 
  23.     usage of BG data
  24.     file name    number of BG    type of matrix    aount
  25.     -------------------------------------------------
  26.     frame_lcd.c 9                8 x 8            9
  27.     break_btn.c    9                8 x 8            9
  28.     press_btn.c 9                8 x 8            9
  29.     dtmf_lcd.c  25                8 x 16            50
  30.     ------------------------------------------------
  31.     total                                        77
  32.  
  33.  
  34.     usage of OBJ data
  35.     file name    number of obj    type of matrix    amount
  36.     --------------------------------------------------
  37.     key_num.c    23                8 x 8            23
  38.     cursor.c    2                16 x 16            8
  39.     --------------------------------------------------
  40.     total                                        31
  41. */
  42.  
  43.  
  44. /* display */
  45. #define TITLE " GB-DTMF BY 05AMU "
  46.  
  47. #define OFFSET             27
  48. #define KEY_STEP         24    /* Key matrix size as 24 x 24    */
  49. #define START_CURSOR_X    24    /* CURSOR position    */
  50. #define START_CURSOR_Y    72
  51.  
  52. #define LCD_X             1    /* start position of X        */
  53. #define LCD_Y            2    /* start position of Y        */
  54. #define LCD_WIDTH        18    /* Horizontal size of LCD    */
  55. #define LCD_HIGHT        2    /* Vertical Size of LCD        */
  56.  
  57.  
  58. #define ON    1
  59. #define OFF    0
  60.  
  61. /* DTMF */
  62. #define DTMF_ON        100UL    /* Tone on time        */
  63. #define DTMF_OFF    100UL    /* Tone off time    */
  64.  
  65. #define MAX_DTMF    30        /* Maximum length of DTMF strings    */
  66.  
  67. /*
  68.     Frequency setting
  69. */
  70. /*
  71.     We have to calculate the frequency as followin formula
  72.     
  73.     DTMF has two set frequency, we have to decide Row & Column
  74.     with each digit('0','1','2'...)
  75. */
  76.  
  77. #define C1 0x94U /* 1209Hz, 1213Hz */
  78. #define C2 0x9EU /* 1336Hz, 1337Hz */
  79. #define C3 0xA7U /* 1477Hz, 1472Hz */
  80. #define C4 0xB0U /* 1633Hz, 1638Hz */
  81.  
  82. #define R1 0x44U /*  697Hz,  697Hz */
  83. #define R2 0x56U /*  770Hz,  770Hz */
  84. #define R3 0x66U /*  852Hz,  851Hz */
  85. #define R4 0x75U /*  941Hz,  942Hz */ 
  86.  
  87. unsigned char row[4] = {R1,R2,R3,R4};    /* DTMF frequency strage of Row */    
  88. unsigned char col[4] = {C1,C2,C3,C4};    /* DTMF frequency strage of Col */
  89.  
  90. /* It is possible to set up initial screen by each BG data. */
  91. unsigned char dtmf_tile[] = {
  92.      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  93.  
  94.      0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
  95.      3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  96.      3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  97.      6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
  98.  
  99.      4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
  100.      4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
  101.      4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
  102.  
  103.      4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
  104.      4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
  105.      4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
  106.  
  107.      4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,11, 9,10,11,
  108.      4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,14,12,13,14,
  109.      4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,17,15,16,17,
  110.  
  111.      4, 9,10,11, 9,10,11, 9,10,11, 9,10,11, 4, 9,10,10,10,10,11,
  112.      4,12,13,14,12,13,14,12,13,14,12,13,14, 4,12,13,13,13,13,14,
  113.      4,15,16,17,15,16,17,15,16,17,15,16,17, 4,15,16,16,16,16,17,
  114.  
  115.      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
  116. };
  117.  
  118. /*
  119.     Button image 
  120.     Normal buttons are created by 3tiles x 3tiles(24pixels x 24pixels)
  121.     Dialing button is created by 6tiles x 3tiles(48pixels x 24pixels)
  122. */
  123. unsigned char break_tile[] = {
  124.      9,10,11,
  125.     12,13,14,
  126.     15,16,17
  127. };
  128.  
  129. unsigned char dialing_break[] = {
  130.      9,10,10,10,10,11,
  131.     12,13,13,13,13,14,
  132.     15,16,16,16,16,17
  133. };
  134.  
  135. unsigned char press_tile[] = {
  136.     18,19,20,
  137.     21,22,23,
  138.     24,25,26
  139. };
  140.  
  141.  
  142. unsigned char dialing_press[] = {
  143.     18,19,19,19,19,20,
  144.     21,22,22,22,22,23,
  145.     24,25,25,25,25,26
  146. };
  147.  
  148. /*
  149.     LCD image at initial & AC
  150. */
  151. unsigned char init_disp[] = {
  152.     59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
  153.     60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60
  154. };
  155.  
  156. char    pad[4][6] = {        /* DTMF Pad assign */
  157.     {'1','2','3','A','%','P'},
  158.     {'4','5','6','B','-','F'},
  159.     {'7','8','9','C',',','?'},
  160.     {'*','0','#','D','s','s'}
  161. };
  162.  
  163. unsigned char disp_tile[MAX_DTMF];
  164.  
  165. /*
  166.     Initialize for sound registers
  167.     ch1, ch2 are used for this routine.
  168. */
  169. void init_dial()
  170. {
  171.  
  172.     NR52_REG = 0x83U;
  173.     NR51_REG = 0x00U;
  174.     NR50_REG = 0x77U;
  175.  
  176.     NR24_REG = 0x87U;
  177.     NR22_REG = 0xffU;
  178.     NR21_REG = 0xbfU;
  179.  
  180.     NR14_REG = 0x87U;
  181.     NR12_REG = 0xffU;
  182.     NR11_REG = 0xbfU;
  183.     NR10_REG = 0x04U;
  184. }
  185.  
  186. /* sound engine for DTMF */
  187. void dialtone(UWORD dtmf_on, UWORD dtmf_off, char str[20])
  188. {
  189.     UBYTE i = 0;
  190.     
  191.     while(str[i]){
  192.         switch(str[i]){
  193.             case '1':
  194.               NR13_REG = R1;
  195.               NR23_REG = C1; 
  196.               break;
  197.             case '2':
  198.               NR13_REG = R1;
  199.               NR23_REG = C2;
  200.               break;
  201.             case '3':
  202.               NR13_REG = R1;
  203.               NR23_REG = C3;    
  204.               break;
  205.             case 'A':
  206.             case 'a':
  207.               NR13_REG = R1;
  208.               NR23_REG = C4;  
  209.               break;
  210.             case '4':
  211.               NR13_REG = R2;
  212.               NR23_REG = C1;    
  213.               break;
  214.             case '5':
  215.               NR13_REG = R2;
  216.               NR23_REG = C2;    
  217.               break;
  218.             case '6':
  219.               NR13_REG = R2;
  220.               NR23_REG = C3;    
  221.               break;
  222.             case 'B':
  223.             case 'b':
  224.               NR13_REG = R2;
  225.               NR23_REG = C4;    
  226.               break;
  227.             case '7':
  228.               NR13_REG = R3;
  229.               NR23_REG = C1;    
  230.               break;
  231.             case '8':
  232.               NR13_REG = R3;
  233.               NR23_REG = C2;    
  234.               break;
  235.             case '9':
  236.               NR13_REG = R3;
  237.               NR23_REG = C3;    
  238.               break;
  239.             case 'C':
  240.             case 'c':
  241.               NR13_REG = R3;
  242.               NR23_REG = C4;    
  243.               break;
  244.             case '*':
  245.               NR13_REG = R4;
  246.               NR23_REG = C1;    
  247.               break;
  248.             case '0':
  249.               NR13_REG = R4;
  250.               NR23_REG = C2;    
  251.               break;
  252.             case '#':
  253.               NR13_REG = R4;
  254.               NR23_REG = C3;    
  255.               break;
  256.             case 'D':
  257.             case 'd':
  258.               NR13_REG = R4;
  259.               NR23_REG = C4;    
  260.               break;
  261.             case ',':
  262.               delay(dtmf_on);    /* keep on */
  263.               delay(dtmf_off);    /* keep off */
  264.              
  265.             default:
  266.               NR51_REG = 0x00U;    /* sound off */
  267.               goto skip;
  268.               
  269.           }
  270.         NR24_REG = 0x87U;    /* ch2 tips */
  271.         NR51_REG = 0x33U;    /* sound on */
  272.         delay(dtmf_on);        /* keep on */
  273.  
  274.         NR51_REG = 0x00U;    /* sound off */
  275.         delay(dtmf_off);    /* keep off */
  276.  
  277.       skip:
  278.         i++;
  279.     }
  280. }
  281.  
  282.  
  283. /* Display looks like 7-SEGMENT LED */
  284. void disp_lcd(UBYTE len, char str[MAX_DTMF])
  285. {
  286.     UBYTE i,j;
  287.  
  288.     j = len;
  289.  
  290.     i=0;
  291.     while(str[i]){
  292.         if(str[i] >= '0'||'9' <= str[i]){
  293.             disp_tile[i] = OFFSET + (str[i] - '0') * 2;
  294.             disp_tile[i+j] = OFFSET + (str[i] - '0') * 2 + 1;
  295.         }
  296.         switch(str[i]){
  297.             case 'A':
  298.                 disp_tile[i] = OFFSET + 10 * 2;
  299.                 disp_tile[i+j] = OFFSET + 10 * 2 + 1;
  300.             break;
  301.             case 'B':
  302.                 disp_tile[i] = OFFSET + 11 * 2;
  303.                 disp_tile[i+j] = OFFSET + 11 * 2 + 1;
  304.             break;
  305.             case 'C':
  306.                 disp_tile[i] = OFFSET + 12 * 2;
  307.                 disp_tile[i+j] = OFFSET + 12 * 2 + 1;
  308.             break;
  309.             case 'D':
  310.                 disp_tile[i] = OFFSET + 13 * 2;
  311.                 disp_tile[i+j] = OFFSET + 13 * 2 + 1;
  312.             break;
  313.             case '#':
  314.                 disp_tile[i] = OFFSET + 14 * 2;
  315.                 disp_tile[i+j] = OFFSET + 14 * 2 + 1;
  316.             break;
  317.             case '*':
  318.                 disp_tile[i] = OFFSET + 15 * 2;
  319.                 disp_tile[i+j] = OFFSET + 15 * 2 + 1;
  320.             break;
  321.             case ' ':
  322.                 disp_tile[i] = OFFSET + 16 * 2;
  323.                 disp_tile[i+j] = OFFSET + 16 * 2 + 1;
  324.             break;
  325.             case 'Y':
  326.                 disp_tile[i] = OFFSET + 17 * 2;
  327.                 disp_tile[i+j] = OFFSET + 17 * 2 + 1;
  328.             break;
  329.             case 'M':
  330.                 disp_tile[i] = OFFSET + 18 * 2;
  331.                 disp_tile[i+j] = OFFSET + 18 * 2 + 1;
  332.             break;
  333.             case 'U':
  334.                 disp_tile[i] = OFFSET + 19 * 2;
  335.                 disp_tile[i+j] = OFFSET + 19 * 2 + 1;
  336.             break;
  337.             case 'G':
  338.                 disp_tile[i] = OFFSET + 20 * 2;
  339.                 disp_tile[i+j] = OFFSET + 20 * 2 + 1;
  340.             break;
  341.             case '-':
  342.                 disp_tile[i] = OFFSET + 21 * 2;
  343.                 disp_tile[i+j] = OFFSET + 21 * 2 + 1;
  344.             break;
  345.             case 'T':
  346.                 disp_tile[i] = OFFSET + 22 * 2;
  347.                 disp_tile[i+j] = OFFSET + 22 * 2 + 1;
  348.             break;
  349.             case ',':
  350.                 disp_tile[i] = OFFSET + 23 * 2;
  351.                 disp_tile[i+j] = OFFSET + 23 * 2 + 1;
  352.             break;
  353.             case 'F':
  354.                 disp_tile[i] = OFFSET + 24 * 2;
  355.                 disp_tile[i+j] = OFFSET + 24 * 2 + 1;
  356.             break;
  357.             case 'S':
  358.                 disp_tile[i] = OFFSET + ('5' - '0') * 2;
  359.                 disp_tile[i+j] = OFFSET + ('5' - '0') * 2 + 1;
  360.             break;
  361.         }
  362.         i++;
  363.     }
  364. }
  365.  
  366. /* clear display */
  367. void clr_disp()
  368. {
  369.     set_bkg_data(OFFSET, 50, dtmf_lcd);
  370.     set_bkg_tiles(LCD_X, LCD_Y, LCD_WIDTH, LCD_HIGHT, init_disp);
  371. }
  372.  
  373. /*
  374.     CAUTION: Don't display the NULL code
  375. */
  376. void disp(char str[MAX_DTMF])
  377. {
  378.     UBYTE no, left_pos;
  379.     UBYTE i, start_ch, end_ch;
  380.     char work[MAX_DTMF];
  381.  
  382.     clr_disp();
  383.  
  384.     no = 0;
  385.     while(str[no]){
  386.         no++;
  387.     }
  388.  
  389.     if(no >= LCD_WIDTH){
  390.         start_ch = no - LCD_WIDTH;
  391.         end_ch = LCD_WIDTH;
  392.     }
  393.     else{
  394.         start_ch = 0;
  395.         end_ch = no;
  396.     }
  397.     for(i = 0;i < end_ch;i++){
  398.         work[i] = str[i+start_ch];
  399.     }
  400.     work[end_ch] = 0x00;
  401.  
  402.     disp_lcd(end_ch, work);
  403.  
  404.     left_pos = 19 - end_ch;
  405.     set_bkg_tiles(left_pos, 2, end_ch, LCD_HIGHT, disp_tile);
  406. }
  407.  
  408. void press_button(UBYTE x, UBYTE y)
  409. {
  410.     if(x <= 3 && y <= 3){
  411.         set_bkg_tiles(x * 3 + 1, y * 3 + 5, 3, 3, press_tile);
  412.     }
  413.     if((x == 4 || x == 5) && (y <= 2)){
  414.         set_bkg_tiles(x * 3 + 2, y * 3 + 5, 3, 3, press_tile);
  415.     }
  416.     if((x == 4 || x == 5) && (y == 3)){
  417.         set_bkg_tiles(14, 14, 6, 3, dialing_press);
  418.     }
  419. }
  420.  
  421. void break_button(UBYTE x, UBYTE y)
  422. {
  423.     if(x <= 3 && y <= 3){
  424.         set_bkg_tiles(x * 3 + 1, y * 3 + 5, 3, 3, break_tile);
  425.     }
  426.     if((x == 4 || x == 5) && (y <= 2)){
  427.         set_bkg_tiles(x * 3 + 2, y * 3 + 5, 3, 3, break_tile);
  428.     }
  429.     if((x == 4 || x == 5) && (y == 3)){
  430.         set_bkg_tiles(14, 14, 6, 3, dialing_break);
  431.     }
  432. }
  433.  
  434.  
  435. void init_key()
  436. {
  437.     UBYTE key_x, key_y, i, j;
  438.  
  439.     /* To make numeric KeyPad */
  440.     set_sprite_data(0, 24, key_num);
  441.  
  442.     /* key pad 1 - 3 */
  443.     key_y = KEY_STEP + 40;
  444.     for(i = 1;i <= 3;i++){
  445.         key_x = i * KEY_STEP;
  446.         set_sprite_tile(i, i);
  447.         move_sprite(i, key_x, key_y);
  448.     }
  449.  
  450.     /* key pad 4 - 6 */
  451.     key_y = KEY_STEP * 2 + 40;
  452.     for(i = 4;i <= 6;i++){
  453.         key_x = (i - 3) * KEY_STEP;
  454.         set_sprite_tile(i, i);
  455.         move_sprite(i, key_x, key_y);
  456.     }
  457.  
  458.     /* key pad 7 - 9 */
  459.     key_y = KEY_STEP * 3 + 40;
  460.         for(i = 7;i <= 9;i++){
  461.             key_x = (i - 6) * KEY_STEP;
  462.             set_sprite_tile(i, i);
  463.             move_sprite(i, key_x, key_y);
  464.         }
  465.  
  466.     /* key pad 'A' - 'D' */
  467.     key_x = KEY_STEP * 4;
  468.     for(i = 0;i <= 3;i++){
  469.         key_y = (i+1) * KEY_STEP + 40;
  470.         set_sprite_tile(i+10, i+10);
  471.         move_sprite(i+10, key_x, key_y);
  472.     }
  473.  
  474.     /* key pad '*', '0', '#' */
  475.     set_sprite_tile(15, 15);
  476.     move_sprite(15, KEY_STEP * 1, KEY_STEP * 4 + 40);
  477.     set_sprite_tile(0, 0);
  478.     move_sprite(0, KEY_STEP * 2, KEY_STEP * 4 + 40);
  479.     set_sprite_tile(14, 14);
  480.     move_sprite(14, KEY_STEP * 3, KEY_STEP * 4 + 40);
  481.  
  482.     /* func left */
  483.     key_x = KEY_STEP * 5 + 8;
  484.     for(i = 0;i <= 2;i++){
  485.         key_y = (i+1) * KEY_STEP + 40;
  486.         set_sprite_tile(i+16, i+16);
  487.         move_sprite(i+16, key_x, key_y);
  488.     }
  489.  
  490.     /* func right */
  491.     key_x = KEY_STEP * 6 + 8;
  492.     for(i = 0;i <= 2;i++){
  493.         key_y = (i+1) * KEY_STEP + 40;
  494.         set_sprite_tile(i+19, i+19);
  495.         move_sprite(i+19, key_x, key_y);
  496.     }
  497.  
  498.     /* dialing button */
  499.     key_x = KEY_STEP * 5 + 20;
  500.     key_y = KEY_STEP * 4 + 40;
  501.     set_sprite_tile(22, 22);
  502.     move_sprite(22, key_x, key_y);
  503. }
  504.  
  505. void init_bkg()
  506. {
  507.     /* Initialize the background */
  508.     set_bkg_data( 0, 9, frame_lcd);
  509.     set_bkg_data( 9, 9, break_btn);
  510.     set_bkg_data(18, 9, press_btn);
  511.     
  512.     set_bkg_tiles(0, 0, 20, 18, dtmf_tile);
  513. }
  514.  
  515. void init_cursor()
  516. {
  517.     UBYTE i;
  518.  
  519.     /* Setup the cursor data*/
  520.     set_sprite_data(23, 8, cursor_data);
  521.  
  522.     for(i = 23;i <= 30;i++){
  523.         set_sprite_tile(i, i);
  524.     }
  525. }
  526.  
  527. void move_cursor(UBYTE x, UBYTE y)
  528. {
  529.     move_sprite(23, x, y);
  530.     move_sprite(24, x, y+8);
  531.     move_sprite(25, x+8, y);
  532.     move_sprite(26, x+8, y+8);
  533. }
  534.  
  535. void main()
  536. {
  537.     UBYTE key1, key2, i, j, pos_x, pos_y, ch_pos;
  538.     UBYTE non_flick = OFF;
  539.     UWORD on_time, off_time;
  540.  
  541.     char str[MAX_DTMF];
  542.     char str_ms[10];
  543.  
  544.     /* default dialling time setting */
  545.     on_time = DTMF_ON;
  546.     off_time = DTMF_OFF;
  547.  
  548.     disable_interrupts();
  549.     
  550.     SPRITES_8x8;   /* sprites are 8x8 */
  551.  
  552.     init_dial();
  553.     
  554.     init_bkg();
  555.     
  556.     init_key();
  557.  
  558.     init_cursor();
  559.  
  560.     disp(TITLE);
  561.  
  562.     SHOW_BKG;
  563.     SHOW_SPRITES;
  564.     DISPLAY_ON;
  565.  
  566.     enable_interrupts();
  567.     
  568.     i = j = 0;
  569.  
  570.     ch_pos = 0;
  571.     
  572.     while(1) {
  573.         wait_vbl_done();
  574.         key1 = joypad();
  575.  
  576.         if(key1 != key2){
  577.             pos_x = i * KEY_STEP + START_CURSOR_X;
  578.             pos_y = j * KEY_STEP + START_CURSOR_Y;
  579.             move_cursor(pos_x, pos_y);
  580.         }
  581.  
  582.         if(key2 & J_A){
  583.             if(key1 & J_A){
  584.                 /* value set for each sound reg only numeric key pad*/
  585.                 if(i <= 3 && j <= 3){
  586.                     /* frequncy register set up for DTMF */
  587.                     NR13_REG = row[i];
  588.                     NR23_REG = col[j];
  589.                     NR24_REG = 0x87U;
  590.  
  591.                     /* sound output on */
  592.                     NR51_REG = 0x33U;
  593.                 }
  594.                 
  595.                 /* '?' button */
  596.                 /* appear the title during press A button */
  597.                 if(i == 5 && j == 0 && !non_flick){
  598.                     disp(TITLE);
  599.                     non_flick = ON;
  600.                 }
  601.  
  602.                 /* incremental button */
  603.                 /* decremental button */
  604.                 /* appear the delay during press A button */
  605.                 if(i == 5 && (j == 1 || j == 2) && !non_flick){
  606.                     sprintf(str_ms, "%lu MS", on_time);
  607.                     disp(str_ms);
  608.                     non_flick = ON;
  609.                 }
  610.             }
  611.             else{
  612.                 /* sound output off */
  613.                 NR51_REG = 0x00U;
  614.  
  615.                 break_button(i, j);
  616.  
  617.                 /* '?' button */
  618.                 /* incremental button */
  619.                 /* decremental button */
  620.                 /* return to normal display at release the A button */
  621.                 if(i == 5 && (j == 0 || j == 1 || j == 2)){
  622.                     non_flick = OFF;
  623.                     if(ch_pos == 0)
  624.                         clr_disp();
  625.                     else
  626.                         disp(str);
  627.                 }
  628.             }
  629.         }
  630.         else{
  631.             if(key1 & J_A){
  632.                 /* button display handle */
  633.                 press_button(i, j);
  634.  
  635.                 /* numeric key pad handling */
  636.                 if(i <= 3 && j <= 3){
  637.                     /* string length check */
  638.                     if(ch_pos < MAX_DTMF-1){
  639.                         str[ch_pos] = pad[j][i];
  640.                         ch_pos++;
  641.                         str[ch_pos] = 0x00;
  642.                         disp(str);
  643.                     }
  644.                 }
  645.  
  646.                 /* ',' button */
  647.                 if(i == 4 && j == 2){
  648.                     /* string length check */
  649.                     if(ch_pos < MAX_DTMF-1){
  650.                         str[ch_pos] = pad[j][i];
  651.                         ch_pos++;
  652.                         str[ch_pos] = 0x00;
  653.                         disp(str);
  654.                     }
  655.                 }
  656.  
  657.                 /* all clear button */
  658.                 if(i == 4 && j == 0){
  659.                     ch_pos = 0x00;
  660.                     strcpy(str,"");
  661.                     clr_disp();
  662.                 }
  663.  
  664.                 /* delete button */
  665.                 if(i == 4 && j == 1){
  666.                     if(ch_pos > 0){
  667.                         ch_pos--;
  668.                         str[ch_pos] = 0x00;
  669.                         if(ch_pos == 0)
  670.                             clr_disp();
  671.                         else
  672.                             disp(str);
  673.                     }
  674.                 }
  675.  
  676.                 /* incremental button */
  677.                 if(i == 5 && j == 1){
  678.                     if(on_time >= DTMF_ON / 2){
  679.                         on_time = on_time - 10;
  680.                         off_time = off_time - 10;
  681.                     }
  682.                 }
  683.  
  684.                 /* decremental button */
  685.                 if(i == 5 && j == 2){
  686.                     if(on_time <= DTMF_ON * 2){
  687.                         on_time = on_time + 10;
  688.                         off_time = off_time + 10;
  689.                     }
  690.                 }
  691.  
  692.                 /* dialing button */
  693.                 if((i==4 || i==5) && j==3){
  694.                     dialtone(on_time, off_time, str);
  695.                 }
  696.             }
  697.         }
  698.  
  699.         if(!(key1 & J_A)){
  700.             if((key1 & J_UP) && !(key2 & J_UP) && j > 0)
  701.                 j--;
  702.             else if((key1 & J_DOWN) && !(key2 & J_DOWN) && j < 3)
  703.                 j++;
  704.  
  705.             if((key1 & J_LEFT) && !(key2 & J_LEFT) && i > 0)
  706.                 i--;
  707.             else if((key1 & J_RIGHT) && !(key2 & J_RIGHT) && i < 5)
  708.                 i++;
  709.         }
  710.         key2 = key1;
  711.     }
  712. }
  713.